package com.atmilan.quartz.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.atmilan.quartz.constant.Constants;
import com.atmilan.quartz.mapper.SystemConfigMapper;
import com.atmilan.quartz.model.entity.crmeb.SystemConfig;
import com.atmilan.quartz.service.ISystemConfigService;
import com.atmilan.quartz.utils.RedisUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
* @author Mr.Zhang
* @Description SystemConfigServiceImpl 接口实现
* @since 2020-04-13
*/
@Service
public class SystemConfigServiceImpl extends ServiceImpl<SystemConfigMapper, SystemConfig> implements ISystemConfigService {
    @Value("${server.asyncConfig}")
    private Boolean asyncConfig;
    private static final String redisKey = Constants.CONFIG_LIST;
    
    @Autowired
    private RedisUtil redisUtil;

    /**
     * 同时获取多个配置
     * @param keys 多个配置key
     * @return 查询到的数据集合
     */
    @Override
    public List<String> getValuesByKes(List<String> keys) {
        List<String> result = new ArrayList<>();
        for (String key : keys) {
            result.add(getValueByKey(key));
        }
        return result;
    }

    /**
     * 根据 name 获取 value 找不到抛异常
     * @param name menu name
     * @author Mr.Zhang
     * @since 2020-04-16
     * @return String
     */
    @Override
    public String getValueByKeyException(String name) {
        String value = get(name);
        if (null == value) {
            log.warn("没有找到" + name + "数据");
        }

        return value;
    }

    /**
     * 根据menu name 获取 value
     * @param name menu name
     * @author Mr.Zhang
     * @since 2020-04-16
     * @return String
     */
    @Override
    public String getValueByKey(String name) {
        return get(name);
    }

    /**
     * 把数据同步到redis
     * @param name String
     * @author Mr.Zhang
     * @since 2020-04-16
     * @return JSONObject
     */
    private String get(String name) {
        if (!asyncConfig) {
            //如果配置没有开启
            SystemConfig systemConfig = getOne(Wrappers.<SystemConfig>lambdaQuery()
                    .eq(SystemConfig::getStatus, false)
                    .eq(SystemConfig::getName, name));
            
            if (null == systemConfig || StringUtils.isBlank(systemConfig.getValue())) {
                return null;
            }

            return systemConfig.getValue();

        }
        setRedisByVoList();
        Object data = redisUtil.hmGet(redisKey, name);
        if (null == data || StringUtils.isBlank(data.toString())) {
            //没有找到数据
            return null;
        }

        //去数据库查找，然后写入redis
        return data.toString();
    }
    
    /**
     * 把数据同步到redis, 此方法适用于redis为空的时候进行一次批量输入
     * @author Mr.Zhang
     * @since 2020-04-16
     * @return JSONObject
     */
    private void setRedisByVoList(){
        //检测redis是否为空
        Long size = redisUtil.getHashSize(redisKey);
        if(size > 0 || !asyncConfig){
            return;
        }

        List<SystemConfig> systemConfigList = list(Wrappers.<SystemConfig>lambdaQuery()
                .eq(SystemConfig::getStatus, false)
                );
        
        async(systemConfigList);
    }
    
    /**
     * 把数据同步到redis
     * @param systemConfigList List<SystemConfig> 需要同步的数据
     * @author Mr.Zhang
     * @since 2020-04-16
     * @return JSONObject
     */
    private void async(List<SystemConfig> systemConfigList){
        if (!asyncConfig) {
            //如果配置没有开启
            return;
        }

        for (SystemConfig systemConfig : systemConfigList) {
            if(systemConfig.getStatus()){
                //隐藏之后，删除redis的数据
                deleteRedis(systemConfig.getName());
                continue;
            }
            redisUtil.hmSet(redisKey, systemConfig.getName(), systemConfig.getValue());
        }
    }

    /**
     * 把数据同步到redis
     * @param name String
     * @author Mr.Zhang
     * @since 2020-04-16
     * @return JSONObject
     */
    private void deleteRedis(String name){
        if (!asyncConfig) {
            //如果配置没有开启
            return;
        }
        redisUtil.hmDelete(redisKey, name);
    }

}
